﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Routing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.Web.Mvc;

namespace MvcSupplantCaching.UnitTests
{
    public class BaseTest
    {
        public BaseTest()
        {
            HttpContext = new Mock<HttpContextBase>();
            HttpRequest = new Mock<HttpRequestBase>();
            HttpResponse = new Mock<HttpResponseBase>();
            HttpSessionState = new Mock<HttpSessionStateBase>();
            HttpServerUtility = new Mock<HttpServerUtilityBase>();

            OutputWriter = new StringWriter();

            var form = new NameValueCollection();
            var queryString = new NameValueCollection();
            HttpRequest.Setup(r => r.Form).Returns(form);
            HttpRequest.Setup(r => r.QueryString).Returns(queryString);
            HttpContext.Setup(ctx => ctx.Request).Returns(HttpRequest.Object);
            HttpContext.Setup(ctx => ctx.Response).Returns(HttpResponse.Object);
            HttpContext.Setup(ctx => ctx.Session).Returns(HttpSessionState.Object);
            HttpContext.Setup(ctx => ctx.Server).Returns(HttpServerUtility.Object);
            HttpContext.Setup(ctx => ctx.Response.Output).Returns(OutputWriter);
        }


        public Mock<ControllerContext> GetMockControllerContext(string varyByCustomString, RouteData routeData)
        {
            var mockContext = new Mock<ControllerContext>();
            if (!string.IsNullOrEmpty(varyByCustomString))
            {
                var mockApplication = new Mock<HttpApplication>();
                mockApplication.Setup(a => a.GetVaryByCustomString(It.IsAny<HttpContext>(), It.IsAny<string>())).Returns<HttpContext, string>((ctx, str) => varyByCustomString);
                HttpContext.Setup(c => c.ApplicationInstance).Returns(mockApplication.Object);
            }
            mockContext.Setup(c => c.RouteData).Returns(routeData);
            mockContext.Setup(c => c.HttpContext).Returns(HttpContext.Object);
            mockContext.Setup(s => s.IsChildAction).Returns(false);
            return mockContext;
        }

        public Mock<ActionExecutingContext> GetMockActionExecutingContext(string varyByCustomString, RouteData routeData)
        {
            var mockContext = new Mock<ActionExecutingContext>();
            if (!string.IsNullOrEmpty(varyByCustomString))
            {
                var mockApplication = new Mock<HttpApplication>();
                mockApplication.Setup(a => a.GetVaryByCustomString(It.IsAny<HttpContext>(), It.IsAny<string>())).Returns<HttpContext, string>((ctx, str) => varyByCustomString);
                HttpContext.Setup(c => c.ApplicationInstance).Returns(mockApplication.Object);
            }
            mockContext.Setup(c => c.RouteData).Returns(routeData);
            mockContext.Setup(c => c.HttpContext).Returns(HttpContext.Object);
            mockContext.Setup(s => s.IsChildAction).Returns(false);
            return mockContext;
        }

        public Mock<HttpContextBase> HttpContext;
        public Mock<HttpRequestBase> HttpRequest;
        public Mock<HttpResponseBase> HttpResponse;
        public Mock<HttpSessionStateBase> HttpSessionState;
        public Mock<HttpServerUtilityBase> HttpServerUtility;
        public StringWriter OutputWriter;
    }
}
